#include "stdafx.h"
#include "Bus.h"

using namespace std;
extern ofstream log;

Bus::Bus()
{
	mCurBit = true;
	mOldBits.clear();
	mCurStatus = Idle;
	mOldStatuses.clear();
}

Bus::~Bus()
{
	mOldBits.clear();
	mOldStatuses.clear();
}

bool Bus::getCurBit()
{
	return mCurBit;
}

bool Bus::getPrvBit()
{
	if(!mOldBits.empty())
	{
		return mOldBits.back();
	}
	else
	{
		//throw exception here
		return true;
	}
}

void Bus::trySetCurBit(bool bit)
{
	mCurBit = mCurBit && bit;
}

BusStatus Bus::getPrvStatus()
{
	if(!mOldStatuses.empty())
	{
		return mOldStatuses.back();
	}
	else
	{
		//throw exception here
		return Any;
	}
}

BusStatus Bus::getCurStatus()
{
	return mCurStatus;
}

void Bus::setCurStatus(BusStatus status)
{
	mCurStatus = status;
}

/*
enum BusStatus
{
	InDRFrame,	//in Data or Remote Frame
	InErrorFrame,
	InOverloadFrame,
	Intermission,
	SuspendTransmission,
	Idle,
	Wrong, //indicates that Bus is malfunctioning
	Any //means any status
};
*/
void Bus::run()
{
	int i = 1;
	int index = 0;
	bool bit = true;

	//Save previous status
	mOldStatuses.push_back(mCurStatus);
	//Save previous bit
	mOldBits.push_back(mCurBit);

	//Change status
	switch(mCurStatus)
	{
	case Idle: 
		log << "Bus is in Idle stauts." << endl;
		//If Bus is Idle and detects StartOfFrame, it needs to shift status to InDRFrame
		if(!mCurBit) 
		{
			mCurStatus = InDRFrame;
		}
		break;
	case InDRFrame:
		log << "Bus is in InDRFrame stauts." << endl;
		//If detect EndOfFrame, Bus needs to shift status to Idle
		index = mOldBits.size();
		if(index>=44) //A data or remote frame is at least 44 bits long
		{
			while(bit && (i<=7))
			{
				bit = bit && mOldBits[index-i];
				i++;
			};
			if(bit)
			{
				mCurStatus = Idle;//needfix
			}
		}
		break;
	default: break;
	}	

	//Initialize current bit
	mCurBit = true;
}